package boundarys;

import java.awt.Label;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

import ccrm.BoundryControl;
import controllers.ManageTypesController;
import entitys.Category;
import entitys.Reply;
import entitys.Type;
import enums.Command;
import enums.Result;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.InputMethodEvent;

public class ManageTypesGUI extends AbstractGUI {

	/**
	 * Manage types frame
	 */
	private JFrame frmmanageTypes;
	/**
	 * List of product types to store the result from server
	 */
	ArrayList<Type> arr=null;
	/**
	 * List of product types to add to the frame list
	 */
	private List productsTypeList;
	/**
	 * Labels
	 */
	private Label searchLabel;
	private Label typeNameLabel;
	private Label typesindbLabel;
	/**
	 * Buttons
	 */
	private JButton BackBtn;
	private JButton ClearBtn;
	private JButton ConfirmBtn;
	private JButton AddTypeBtn;
	private JButton RefreshBtn;
	private JButton EditTypeBtn;
	private JButton DeleteTypeBtn;
	/**
	 * type text field
	 */
	private JTextField typetextField;
	/**
	 * search text field
	 */
	private JTextField searchTextField;

	/**
	 * Constructor
	 */
	public ManageTypesGUI() {
		initialize();
		initGUI(frmmanageTypes);

	}

	/**
	 * 
	 * @return product types list
	 */
	public List getProductsTypeList() {
		return productsTypeList;
	}

	/**
	 * sets the product type list
	 * @param productsTypeList
	 */
	public void setProductsTypeList(List productsTypeList) {
		this.productsTypeList = productsTypeList;
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmmanageTypes = new JFrame();
		/**
		 * Mouse Listener
		 * Whenever the frame is clicked it deselects the selected item in list
		 */
		frmmanageTypes.getContentPane().addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				productsTypeList.deselect(productsTypeList.getSelectedIndex());	
			}
		});
		frmmanageTypes.setTitle("...Manage Product Category/Type>Manage Types");
		frmmanageTypes.setResizable(false);
		frmmanageTypes.setBounds(100, 100, 466, 426);
		frmmanageTypes.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		
		frmmanageTypes.getContentPane().setLayout(null);
		
		productsTypeList = new List();
		/**
		 * Mouse Listener
		 * Whenever product type is selected it sets the text field text to the product type name
		 */
		productsTypeList.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent arg0) {
				String tmp = (String)productsTypeList.getSelectedItem();
				typetextField.setText(tmp.substring(tmp.indexOf(" ")).trim());
			}
		});

		productsTypeList.setMultipleSelections(false);
		productsTypeList.setBounds(35, 75, 219, 221);
		frmmanageTypes.getContentPane().add(productsTypeList);
		
		/**
		 * sends the server a request to get product types list
		 */
		ManageTypesController.getProductTypes();
		
		typesindbLabel = new Label("Product types in db");
		typesindbLabel.setBounds(35, 47, 203, 22);
		frmmanageTypes.getContentPane().add(typesindbLabel);
		
		typeNameLabel = new Label("Type name:");
		typeNameLabel.setBounds(9, 314, 90, 22);
		frmmanageTypes.getContentPane().add(typeNameLabel);
		
	    RefreshBtn = new JButton("Refresh");
		/**
		 * Action Listener for Refresh Button
		 * Gets the updated product types list and shows it in the list
		 */
		RefreshBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)
				{
					searchTextField.setText("");
					ManageTypesController.getProductTypes();
				}
			}
		});
		RefreshBtn.setBounds(286, 237, 137, 43);
		frmmanageTypes.getContentPane().add(RefreshBtn);
		
		typetextField = new JTextField();
		typetextField.setBounds(101, 314, 153, 22);
		frmmanageTypes.getContentPane().add(typetextField);
		
		BackBtn = new JButton("Back");
		/**
		 * Action Listener for Back Button
		 * goes to previous frame
		 */
		BackBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				goBack();
			}
		});
		BackBtn.setBounds(9, 361, 89, 23);
		frmmanageTypes.getContentPane().add(BackBtn);
		
		AddTypeBtn = new JButton("Add Type");
		/**
		 * Action Listener for Add Type Button
		 * if the type already exists or the name is empty it does not add 
		 * else adds new type to list and database
		 */
		AddTypeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)
				{
					if(productsTypeList.getSelectedItem()!=null)
					{
						JOptionPane.showMessageDialog(frmmanageTypes, "Unable to add an existing type", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
					}
					else if(typetextField.getText().equals(""))
					{
						JOptionPane.showMessageDialog(frmmanageTypes, "Please enter a type name", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
					}
					else if(exists(productsTypeList, typetextField.getText()))
					{
						JOptionPane.showMessageDialog(frmmanageTypes, "Unable to add an existing type", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
					}
					else
					{
						ManageTypesController.addType(typetextField.getText(), getProductsTypeList().getItemCount());//send request to add category
					}
				}
			}
		});
		AddTypeBtn.setBounds(286, 75, 137, 43);
		frmmanageTypes.getContentPane().add(AddTypeBtn);
		
		EditTypeBtn = new JButton("Edit Type");
		/**
		 * Action Listener for Edit Type Button
		 * if the type is not selected or the new type name is the same or empty or already exists it shows corresponding message 
		 * else adds changes type name in list and updates the database
		 */
		EditTypeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)
				{
					String selected = (String)productsTypeList.getSelectedItem();
					
					if(productsTypeList.getSelectedItem() == null)
						JOptionPane.showMessageDialog(frmmanageTypes, "Select a type to edit", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
					else{
						String newtype = JOptionPane.showInputDialog(frmmanageTypes, "Enter new name for selected type:", "CCRM>Edit Types", JOptionPane.OK_CANCEL_OPTION);
						int tid = Integer.parseInt(selected.substring(1,selected.indexOf(" ")).trim());
						if(newtype.equals(selected.substring(selected.indexOf(" ")).trim()))
							JOptionPane.showMessageDialog(frmmanageTypes, "New type name must be different", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
						else if(exists(productsTypeList, newtype))
							JOptionPane.showMessageDialog(frmmanageTypes, "Product type already exists", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
						else if(newtype.equals(""))
							JOptionPane.showMessageDialog(frmmanageTypes, "New type name must be not empty", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);	
						else
							ManageTypesController.editType(newtype, tid);
					}
				}
			}
		});
		EditTypeBtn.setBounds(286, 129, 137, 43);
		frmmanageTypes.getContentPane().add(EditTypeBtn);
		
		DeleteTypeBtn = new JButton("Delete Type");
		/**
		 * Action Listener for Delete Type Button
		 * if the type is not selected it shows corresponding message 
		 * else delete type name from list and updates the database
		 */
		DeleteTypeBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)
				{
					if(productsTypeList.getSelectedItem() == null)
						JOptionPane.showMessageDialog(frmmanageTypes, "Select a type to delete", "CCRM Manage Types", JOptionPane.ERROR_MESSAGE);
					else
					{
						String t = (String)productsTypeList.getSelectedItem();
						int tid = Integer.parseInt(t.substring(1,t.indexOf(" ")).trim());
						ManageTypesController.deleteType((String)productsTypeList.getSelectedItem(), tid);
					}
				}
			}
		});
		DeleteTypeBtn.setBounds(286, 183, 137, 43);
		frmmanageTypes.getContentPane().add(DeleteTypeBtn);
	 	
		ClearBtn = new JButton("Clear");
		/**
		 * Action Listener for Clear Button
		 * Clears the type text field
		 */
		ClearBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				if(BoundryControl.GUIArr.size()==getIndex()+1)
				{
					typetextField.setText("");
				}
			}
		});
		ClearBtn.setBounds(270, 313, 89, 23);
		frmmanageTypes.getContentPane().add(ClearBtn);
		
		searchLabel = new Label("Search types:");
		searchLabel.setBounds(35, 10, 98, 22);
		frmmanageTypes.getContentPane().add(searchLabel);
		
		searchTextField = new JTextField();
		/**
		 * Key Listener for search text field
		 * Whenever key is released it updates the type list by showing the names that contains the string that was typed
		 */
		searchTextField.addKeyListener(new KeyAdapter() {
			@Override
			public void keyReleased(KeyEvent e) {
				if(searchTextField.getText().isEmpty())
					ManageTypesController.getProductTypes();
				else
					ManageTypesController.getProductTypes(searchTextField.getText());
			}
		});

		searchTextField.setBounds(138, 10, 137, 22);
		frmmanageTypes.getContentPane().add(searchTextField);
		searchTextField.setColumns(10);
		
		
		frmmanageTypes.setVisible(true);
	}
	
	/**
	 * 
	 * @param l
	 * @param text
	 * @return whether text exists in the list l
	 */
	public boolean exists(List l, String text) {
		for(int i=0;i<l.getItemCount();i++)
		{
			String tmp = (String)l.getItem(i);
			if(text.equals(tmp.substring(tmp.indexOf(" ")).trim()))
				return true;
		}
		return false;
	}

	/**
	 * Reply from server
	 * Does the right action according to the command that was sent from the controller
	 */
	@Override
	public void getReply(Object r) {
		// TODO Auto-generated method stub
		if(((Reply)r).command.equals(Command.GET_PRODUCT_TYPES))
		{
			arr =(ArrayList<Type>) ((Reply)r).result;
			productsTypeList.removeAll();
			
			for(int i=0;i<arr.size();i++)
			{
				productsTypeList.add(arr.get(i).toString());
			}
		}
		
		else if(((Reply)r).command.equals(Command.GET_PRODUCT_TYPES_WITH_PREFIX)) //if GET_PRODUCTS reply is received
		{
			arr =(ArrayList<Type>) ((Reply)r).result;
			productsTypeList.removeAll();
			
			if(!arr.isEmpty())
			{
				for(int i=0;i<arr.size();i++)
				{
					productsTypeList.add(arr.get(i).toString());
				}
			}
		}
		
		else if(((Reply)r).command.equals(Command.ADD_TYPE))
		{
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("Type added successfully!");
				JOptionPane.showMessageDialog(frmmanageTypes, "Type added successfully", "CCRM Manage Types", JOptionPane.INFORMATION_MESSAGE);
			}
			ManageTypesController.getProductTypes();
			
		}
		
		else if(((Reply)r).command.equals(Command.EDIT_TYPE))
		{
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("Type updated successfully!");
				JOptionPane.showMessageDialog(frmmanageTypes, "Type updated successfully", "CCRM Manage Types", JOptionPane.INFORMATION_MESSAGE);
			}
			ManageTypesController.getProductTypes();
			
		}
		
		else if(((Reply)r).command.equals(Command.DELETE_TYPE))
		{
			if (((Reply)r).result.equals(Result.OK))
			{
				System.out.println("Type deleted successfully!");
				JOptionPane.showMessageDialog(frmmanageTypes, "Type deleted successfully", "CCRM Manage Types", JOptionPane.INFORMATION_MESSAGE);
			}
			ManageTypesController.getProductTypes();
			
		}
		
	}
}
